package com.resume.aipeople.service.ai.model;

import ai.z.openapi.service.model.ChatCompletionCreateParams;
import ai.z.openapi.service.model.ChatMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;

import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.List;
import java.util.Map;

/**
 * Gemini模型策略实现
 * 使用Google Gemini 2.5 Flash模型
 */
@Component
@Slf4j
public class GeminiModelStrategy implements LLMModelStrategy {

    @Value("${gemini.api.key:${GEMINI_API_KEY:}}")
    private String geminiApiKey;
    
    @Value("${google.api.key:${GOOGLE_API_KEY:}}")
    private String googleApiKey;
    
    // 代理配置
    @Value("${gemini.api.proxy.enabled:false}")
    private boolean proxyEnabled;
    
    @Value("${gemini.api.proxy.host:127.0.0.1}")
    private String proxyHost;
    
    @Value("${gemini.api.proxy.port:7890}")
    private int proxyPort;
    
    @Value("${gemini.api.proxy.username:}")
    private String proxyUsername;
    
    @Value("${gemini.api.proxy.password:}")
    private String proxyPassword;
    
    // 超时配置
    @Value("${gemini.api.timeout.connect:5000}")
    private int connectTimeout;
    
    @Value("${gemini.api.timeout.read:15000}")
    private int readTimeout;
    
    @Value("${gemini.api.timeout.write:5000}")
    private int writeTimeout;

    private WebClient webClient;

    @Override
    public String getModelName() {
        return "gemini-2.5-flash";
    }

    @Override
    public String getDisplayName() {
        return "Gemini 2.5 Flash";
    }

    @Override
    public String getDescription() {
        return "Google Gemini 2.5 Flash模型，具备强大的多模态理解和生成能力";
    }

    @Override
    public boolean isAvailable() {
        // 检查是否有可用的API Key
        return (geminiApiKey != null && !geminiApiKey.trim().isEmpty()) || 
               (googleApiKey != null && !googleApiKey.trim().isEmpty());
    }

    @Override
    public ChatCompletionCreateParams buildRequest(List<ChatMessage> messages, float temperature, int maxTokens) {
        // Gemini使用不同的请求格式，这里返回null，实际请求在processResponse中处理
        return null;
    }

    @Override
    public Mono<String> processResponse(Object rawContent) {
        return Mono.fromCallable(() -> {
            if (!isAvailable()) {
                log.error("Gemini API Key未配置");
                throw new RuntimeException("Gemini API Key未配置");
            }

            // 初始化WebClient（如果尚未初始化）
            if (webClient == null) {
                // 检查API Key是否配置
                String apiKey = (googleApiKey != null && !googleApiKey.trim().isEmpty()) ? 
                               googleApiKey : geminiApiKey;
                
                if (apiKey == null || apiKey.trim().isEmpty()) {
                    log.error("Gemini API Key未配置");
                    throw new RuntimeException("Gemini API Key未配置");
                }
                
                // 创建HttpClient配置
                HttpClient httpClient = HttpClient.create()
                    .responseTimeout(Duration.ofMillis(readTimeout))
                    .option(io.netty.channel.ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout);
                
                // 配置代理
                if (proxyEnabled) {
                    log.info("配置Gemini代理: {}:{}", proxyHost, proxyPort);
                    httpClient = httpClient.proxy(proxy -> proxy
                        .type(reactor.netty.transport.ProxyProvider.Proxy.HTTP)
                        .address(new InetSocketAddress(proxyHost, proxyPort))
                        .username(proxyUsername.isEmpty() ? null : proxyUsername)
                        .password(password -> proxyPassword.isEmpty() ? null : proxyPassword));
                }
                
                // 创建WebClient实例
                webClient = WebClient.builder()
                    .baseUrl("https://generativelanguage.googleapis.com")
                    .defaultHeader("Content-Type", "application/json")
                    .clientConnector(new org.springframework.http.client.reactive.ReactorClientHttpConnector(httpClient))
                    .build();
                
                log.info("Gemini WebClient初始化完成，API Key: {}...，代理: {}，超时: {}ms", 
                        apiKey.length() > 10 ? apiKey.substring(0, 10) : "null",
                        proxyEnabled ? proxyHost + ":" + proxyPort : "无",
                        readTimeout);
            }

            // 构建消息内容
            StringBuilder contentBuilder = new StringBuilder();
            for (ChatMessage message : (List<ChatMessage>) rawContent) {
                contentBuilder.append(message.getContent()).append("\n");
            }
            String content = contentBuilder.toString().trim();

            log.info("发送Gemini请求 - 模型: {}, 内容长度: {}", getDisplayName(), content.length());

            // 构建请求体 - 使用正确的Gemini API格式，优化参数以提高响应速度
            Map<String, Object> requestBody = Map.of(
                "contents", List.of(
                    Map.of(
                        "role", "user",
                        "parts", List.of(
                            Map.of("text", content)
                        )
                    )
                ),
                "generationConfig", Map.of(
                    "temperature", 0.8,
                    "topK", 20,
                    "topP", 0.9,
                    "maxOutputTokens", 2048
                )
            );

            // 获取API Key
            String apiKey = (googleApiKey != null && !googleApiKey.trim().isEmpty()) ? 
                           googleApiKey : geminiApiKey;

            // 调用Gemini REST API，优化重试机制和超时
            Map<String, Object> response = webClient.post()
                .uri("/v1beta/models/{model}:generateContent?key={key}", getModelName(), apiKey)
                .bodyValue(requestBody)
                .retrieve()
                .bodyToMono(Map.class)
                .retry(1) // 减少重试次数，提高响应速度
                .timeout(Duration.ofMillis(readTimeout))
                .block();

            log.info("Gemini响应 - 成功: {}", response != null);
            log.info("Gemini完整响应: {}", response);

            if (response != null && response.containsKey("candidates")) {
                List<Map<String, Object>> candidates = (List<Map<String, Object>>) response.get("candidates");
                log.info("Gemini候选数量: {}", candidates.size());
                
                if (!candidates.isEmpty()) {
                    Map<String, Object> candidate = candidates.get(0);
                    log.info("Gemini候选内容: {}", candidate);
                    
                    // 检查finishReason
                    String finishReason = (String) candidate.get("finishReason");
                    if ("MAX_TOKENS".equals(finishReason)) {
                        log.warn("Gemini响应被截断，达到最大令牌数限制，尝试获取部分内容");
                    }
                    
                    if (candidate.containsKey("content")) {
                        Map<String, Object> contentObj = (Map<String, Object>) candidate.get("content");
                        log.info("Gemini content对象: {}", contentObj);
                        
                        if (contentObj.containsKey("parts")) {
                            List<Map<String, Object>> parts = (List<Map<String, Object>>) contentObj.get("parts");
                            if (!parts.isEmpty()) {
                                String text = (String) parts.get(0).get("text");
                                if (text != null && !text.trim().isEmpty()) {
                                    log.info("Gemini成功解析文本: {}", text);
                                    return text.trim();
                                }
                            }
                        } else {
                            log.warn("Gemini content对象中没有parts字段，尝试其他解析方式");
                            // 如果content对象中没有parts，可能是其他格式
                            if (contentObj.containsKey("text")) {
                                String text = (String) contentObj.get("text");
                                if (text != null && !text.trim().isEmpty()) {
                                    log.info("Gemini从content.text解析文本: {}", text);
                                    return text.trim();
                                }
                            }
                        }
                    }
                    
                    // 如果没有content.parts结构，尝试其他可能的响应格式
                    if (candidate.containsKey("text")) {
                        String text = (String) candidate.get("text");
                        if (text != null && !text.trim().isEmpty()) {
                            log.info("Gemini从candidate.text解析文本: {}", text);
                            return text.trim();
                        }
                    }
                }
            }

            log.warn("Gemini返回空响应，使用默认回复");
            
            // 根据角色生成更合适的默认回复
            String defaultReply = generateDefaultReply(content);
            return defaultReply;
        })
        .doOnError(error -> log.error("Gemini调用异常: {}", error.getMessage(), error))
        .onErrorReturn("抱歉，我现在遇到了一些技术问题，请稍后再试。");
    }

    /**
     * 生成默认回复
     * @param userMessage 用户消息
     * @return 默认回复
     */
    private String generateDefaultReply(String userMessage) {
        // 根据用户消息内容生成简单的回复
        if (userMessage.contains("你好") || userMessage.contains("hello") || userMessage.contains("hi")) {
            return "你好！很高兴见到你！";
        } else if (userMessage.contains("谢谢") || userMessage.contains("thank")) {
            return "不客气！";
        } else if (userMessage.contains("再见") || userMessage.contains("bye")) {
            return "再见！期待下次聊天！";
        } else if (userMessage.contains("？") || userMessage.contains("?")) {
            return "这是一个很有趣的问题，让我想想...";
        } else {
            return "我理解你的意思，让我为你提供一个回应。";
        }
    }

    /**
     * 直接处理消息列表的Gemini请求
     * @param messages 消息列表
     * @param temperature 温度参数
     * @param maxTokens 最大令牌数
     * @return 响应内容
     */
    public Mono<String> generateResponse(List<ChatMessage> messages, float temperature, int maxTokens) {
        return processResponse(messages);
    }
}
